<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>lib/yuidoc.js - YUIDoc</title>
    <link rel="stylesheet" href="https://yui-s.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="icon" href="../assets/favicon.ico">
    <script src="https://yui-s.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">

<div id="doc">
    <div id="hd" class="yui3-g header">
        <div class="yui3-u-3-4">
                <h1><img src="../assets/css/logo.png" title="YUIDoc" width="117" height="52"></h1>
        </div>
        <div class="yui3-u-1-4 version">
            <em>API Docs for: 0.10.0</em>
        </div>
    </div>
    <div id="bd" class="yui3-g">

        <div class="yui3-u-1-4">
            <div id="docs-sidebar" class="sidebar apidocs">
                <div id="api-list">
                    <h2 class="off-left">APIs</h2>
                    <div id="api-tabview" class="tabview">
                        <ul class="tabs">
                            <li><a href="#api-classes">Classes</a></li>
                            <li><a href="#api-modules">Modules</a></li>
                        </ul>
                
                        <div id="api-tabview-filter">
                            <input type="search" id="api-filter" placeholder="Type to filter APIs">
                        </div>
                
                        <div id="api-tabview-panel">
                            <ul id="api-classes" class="apis classes">
                                <li><a href="../classes/CLI.html">CLI</a></li>
                                <li><a href="../classes/DocBuilder.html">DocBuilder</a></li>
                                <li><a href="../classes/DocParser.html">DocParser</a></li>
                                <li><a href="../classes/DocView.html">DocView</a></li>
                                <li><a href="../classes/Files.html">Files</a></li>
                                <li><a href="../classes/Help.html">Help</a></li>
                                <li><a href="../classes/Main.html">Main</a></li>
                                <li><a href="../classes/Options.html">Options</a></li>
                                <li><a href="../classes/Server.html">Server</a></li>
                                <li><a href="../classes/Utils.html">Utils</a></li>
                                <li><a href="../classes/YUIDoc.html">YUIDoc</a></li>
                            </ul>
                
                
                            <ul id="api-modules" class="apis modules">
                                <li><a href="../modules/yuidoc.html">yuidoc</a></li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="yui3-u-3-4">
                <div id="api-options">
                    Show:
                    <label for="api-show-inherited">
                        <input type="checkbox" id="api-show-inherited" checked>
                        Inherited
                    </label>
            
                    <label for="api-show-protected">
                        <input type="checkbox" id="api-show-protected">
                        Protected
                    </label>
            
                    <label for="api-show-private">
                        <input type="checkbox" id="api-show-private">
                        Private
                    </label>
                    <label for="api-show-deprecated">
                        <input type="checkbox" id="api-show-deprecated">
                        Deprecated
                    </label>
            
                </div>
            
            <div class="apidocs">
                <div id="docs-main">
                    <div class="content">
<h1 class="file-heading">File: lib/yuidoc.js</h1>

<div class="file">
    <pre class="code prettyprint linenums">
/**
 * Copyright (c) 2011, Yahoo! Inc. All rights reserved.
 * Code licensed under the BSD License:
 * https://github.com/yui/yuidoc/blob/master/LICENSE
 */
&#x27;use strict&#x27;;

var fs = require(&#x27;graceful-fs&#x27;);
var rimraf = require(&#x27;rimraf&#x27;);
var path = require(&#x27;path&#x27;);

/**
This is the __module__ description for the &#x60;YUIDoc&#x60; module.

    var options = {
        paths: [ &#x27;./lib&#x27; ],
        outdir: &#x27;./out&#x27;
    };

    var Y = require(&#x27;yuidocjs&#x27;);
    var json = (new Y.YUIDoc(options)).run();

@class YUIDoc
@main yuidoc
*/


YUI.add(&#x27;yuidoc&#x27;, function (Y) {


    /**
     * The default list of configuration options
     * @property OPTIONS
     * @type Object
     * @final
     * @for YUIDoc
     */
    var OPTIONS = {
        quiet: false,
        writeJSON: true,
        outdir: path.join(process.cwd(), &#x27;out&#x27;),
        extension: &#x27;.js&#x27;,
        exclude: &#x27;.DS_Store,.svn,CVS,.git,build_rollup_tmp,build_tmp,node_modules&#x27;,
        norecurse: false,
        version: &#x27;0.1.0&#x27;,
        paths: [],
        themedir: path.join(__dirname, &#x27;themes&#x27;, &#x27;default&#x27;),
        syntaxtype: &#x27;js&#x27;
    };

    /**
     * YUIDoc main class

        var options = {
            paths: [ &#x27;./lib&#x27; ],
            outdir: &#x27;./out&#x27;
        };

        var Y = require(&#x27;yuidoc&#x27;);
        var json = (new Y.YUIDoc(options)).run();

     * @class YUIDoc
     * @module yuidoc
     * @constructor
     * @param config The config object
     */
    Y.YUIDoc = function (config) {
        /**
         * Holds the number of files that we are processing.
         * @property filecount
         * @type Boolean
         * @private
         */
        this.filecount = 0;
        /**
         * Hash map of dirnames to selleck config options.
         * @property selleck
         * @type Object
         * @private
         */
        this.selleck = {};
        /**
         * Holder for the list of files we are processing.
         * @property filemap
         * @type Object
         * @private
         */
        this.filemap = {};
        /**
         * Holder for the list of directories we are processing.
         * @property dirmap
         * @type Object
         * @private
         */
        this.dirmap = {};

        /**
         * Internal holder for configuration options.
         * @property options
         * @type Object
         * @private
         */
        this.options = Y.merge(OPTIONS, config);

        if (this.options.quiet) {
            Y.applyConfig({
                debug: false
            });
        }

    };

    Y.YUIDoc.prototype = {
        /**
         * Always exclude these directories
         * @method _setDefaultExcludes
         * @private
         */
        _setDefaultExcludes: function () {
            //These should always be excluded
            var excludes = &#x27;.DS_Store,.svn,CVS,.git,build_rollup_tmp,build_tmp,node_modules&#x27;.split(&#x27;,&#x27;),
                self = this;

            excludes.forEach(function (item) {
                self.options.excludes[item] = true;
            });
        },

        /**
         * Does post process on self.options.
         * @method _processConfig
         * @private
         */
        _processConfig: function () {
            this.options.extensions = Y.Array.hash(this.options.extension.split(&#x27;,&#x27;));
            this.options.excludes = Y.Array.hash(this.options.exclude.split(&#x27;,&#x27;));
            this._setDefaultExcludes();
        },

        /**
         * Walks the paths and parses the directory contents
         * @method walk
         * @private
         */
        walk: function () {
            Y.each(this.options.paths, function (dir) {
                this.parsedir(dir);
            }, this);
        },

        /**
         * Walks the passed directory and grabs all the files recursively.
         * @method parsedir
         * @param {String} dir The directory to parse the contents of.
         * @private
         */
        parsedir: function (dir) {
            if (!Y.Files.isDirectory(dir)) {
                throw (&#x27;Can not find directory: &#x27; + dir);
            }

            var allfiles = fs.readdirSync(dir),
                stats,
                files = [],
                fullpath, self = this;

            if (dir in self.options.excludes) {
                return;
            }

            allfiles = allfiles.sort();

            Y.each(allfiles, function (filename) {
                if (!(filename in self.options.excludes)) {
                    fullpath = path.join(dir, filename);

                    stats = fs.statSync(fullpath);

                    if (stats.isDirectory() &amp;&amp; !self.options.norecurse) {
                        self.parsedir(fullpath);
                    } else {
                        files.push(filename);
                    }
                }
            });

            if (!(dir in self.options.excludes)) {
                this.parsefiles(dir, files);
            }
        },

        /**
         * Gathers all the file data and populates the filemap and dirmap hashes.
         * @method parsefiles
         * @param {String} dir The directory to start from.
         * @param {Array} files List of files to parse.
         * @private
         */
        parsefiles: function (dir, files) {
            var self = this;
            files = files.sort();

            Y.each(files, function (filename) {
                var ext = path.extname(filename),
                    text,
                    fullpath;

                if (ext) {
                    if (ext in self.options.extensions) {
                        fullpath = path.join(dir, filename);

                        if (Y.Files.exists(fullpath)) {
                            self.filecount++;
                            text = fs.readFileSync(fullpath, Y.charset);

                            self.filemap[fullpath] = text.replace(/\r?\n|\r/g, &#x27;\n&#x27;);
                            self.dirmap[fullpath] = dir;
                            self.getSelleck(fullpath);

                        } else {
                            Y.log(&#x27;File skipped: &#x27; + fullpath, &#x27;warn&#x27;, &#x27;yuidoc&#x27;);
                        }
                    }
                }
            });
        },

        getSelleck: function (fullpath) {
            var self = this,
                base,
                comp,
                json;

            if (self.options.selleck) {
                base = path.dirname(fullpath);
                comp = path.join(base, &#x27;../&#x27;, &#x27;docs&#x27;, &#x27;component.json&#x27;);
                //Y.log(&#x27;Checking for Selleck data: &#x27; + comp, &#x27;info&#x27;, &#x27;yuidoc&#x27;);
                if (Y.Files.exists(comp)) {
                    try {
                        json = JSON.parse(fs.readFileSync(comp, &#x27;utf8&#x27;));
                        delete json.examples; //Remove the selleck example data, we only want the comp info
                        self.selleck[fullpath] = json;
                    } catch (e) {
                        Y.log(&#x27;JSON parse failed on Selleck component.json file: &#x27; + comp, &#x27;error&#x27;, &#x27;yuidoc&#x27;);
                    }
                }
            }
        },

        /**
         * Applies preprocessors to the data tree.
         * This function first clones the data and operates on the clone.
         * @method runPreprocessors
         * @private
         * @return {Object} The mutated data
         */
        runPreprocessors: function (data) {
            var self = this,
                preprocessors,
                preprocessorsRelativeTo;

            // We will try to load the preprocessors as npm modules, but we will also
            // search for them relative to the process working directory.
            // The latter is consistent with how other paths are treated by yuidoc,
            // such as the config options &#x27;paths&#x27; and &#x27;outdir&#x27;.
            preprocessorsRelativeTo = process.cwd();

            if (self.options.preprocessor) {
                data = JSON.parse(JSON.stringify(data));

                preprocessors = [].concat(self.options.preprocessor);

                preprocessors.forEach(function (preprocessor) {
                    var preprocessorModule;

                    try {
                        preprocessorModule = require(preprocessor);
                    } catch (e) {
                        preprocessorModule = require(path.resolve(preprocessorsRelativeTo, preprocessor));
                    }

                    preprocessorModule(data, self.options);
                });
            }

            return data;
        },

        /**
         * Writes the parser JSON data to disk.
         * Applies preprocessors, if any.
         * @method writeJSON
         * @param {Object} parser The DocParser instance to use
         * @private
         * @return {Object} The JSON data returned from the DocParser
         */
        writeJSON: function (parser) {
            var self = this,
                data,
                file,
                out;

            data = parser.data;

            data.warnings = parser.warnings;

            data = this.runPreprocessors(data);

            if (self.selleck &amp;&amp; self.options.selleck &amp;&amp; data.files &amp;&amp; data.modules) {
                Object.keys(self.selleck).forEach(function (selleckFile) {
                    Object.keys(data.files).forEach(function (f) {
                        if (selleckFile === f) {
                            var mods = data.files[f].modules;
                            if (mods) {
                                Object.keys(mods).forEach(function (mod) {
                                    if (data.modules[mod]) {
                                        if (!data.modules[mod].extra) {
                                            data.modules[mod].extra = {};
                                        }
                                        data.modules[mod].extra.selleck = self.selleck[selleckFile];
                                    }
                                });
                            }
                        }
                    });
                });
            }

            if (self.options.project) {
                data.project = self.options.project;
            }

            if (self.options.writeJSON) {
                // Y.log(Y.JSON.stringify(parser.data, null, 4));
                file = path.join(self.options.outdir, &#x27;data.json&#x27;);

                if (Y.Files.exists(self.options.outdir) &amp;&amp; !self.options.nodeleteout) {
                    Y.log(&#x27;Found out dir, deleting: &#x27; + self.options.outdir, &#x27;warn&#x27;, &#x27;yuidoc&#x27;);
                    rimraf.sync(self.options.outdir);
                }

                if (!Y.Files.exists(self.options.outdir)) {
                    Y.log(&#x27;Making out dir: &#x27; + self.options.outdir, &#x27;info&#x27;, &#x27;yuidoc&#x27;);
                    try {
                        fs.mkdirSync(self.options.outdir, &#x27;0777&#x27;);
                    } catch (e) {
                        Y.log(&#x27;Outdir creation failed&#x27;, &#x27;warn&#x27;, &#x27;yuidoc&#x27;);
                    }
                }

                out = fs.createWriteStream(file, {
                    flags: &#x27;w&#x27;,
                    encoding: Y.charset,
                    mode: &#x27;0644&#x27;
                });
                out.write(JSON.stringify(data, null, 4));
                out.end();
            }

            return data;
        },

        lint: function (warnings) {
            var code = 0,
                count = 0;

            if (warnings &amp;&amp; warnings.length) {
                code = 1;
                console.log(&#x27;YUIDoc found&#x27;, warnings.length, &#x27;lint errors in your docs&#x27;);
                warnings.forEach(function (item) {
                    count++;
                    console.log(&#x27;#&#x27; + count, item.message, item.line + &#x27;\n&#x27;);
                });
                process.exit(code);
            }
        },

        /**
         * Process the config, walk the file tree and write out the JSON data.
         * @method run
         * @return {Object} The JSON data returned from the DocParser
         */
        run: function () {
            /**
             * Timestamp holder so we know when YUIDoc started the parse process.
             * @property starttime
             * @type Timestamp
             */
            Y.log(&#x27;YUIDoc Starting from: &#x27; + this.options.paths.join(&#x27;,&#x27;), &#x27;info&#x27;, &#x27;yuidoc&#x27;);
            this.starttime = new Date().getTime();

            this._processConfig();
            this.walk();

            var json = this.writeJSON(new Y.DocParser({
                syntaxtype: this.options.syntaxtype,
                filemap: this.filemap,
                dirmap: this.dirmap
            }).parse());

            if (this.options.lint) {
                this.lint(json.warnings);
                return null;
            }

            /**
             * Timestamp holder so we know when YUIDoc has finished the parse process.
             * @property endtime
             * @type Timestamp
             */
            this.endtime = new Date().getTime();
            Y.log(&#x27;Parsed &#x27; + this.filecount + &#x27; files in &#x27; + ((this.endtime - this.starttime) / 1000) + &#x27; seconds&#x27;, &#x27;info&#x27;, &#x27;yuidoc&#x27;);

            return json;
        }
    };

});

    </pre>
</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>
